K.App( 'apps/common/AScrollTip', ['core/jQuery', 'core/Geometry', 'core/ScrollObserver'] ).define( function(require) {

    var $ = require('core/jQuery'),
        Geometry = require('core/Geometry'),
        ScrollObserver = require('core/ScrollObserver'),
        referDOMID = 'footer',
        referDOM = $('#'+referDOMID),
        scrollTipID = '_j_btop',
        scrollTipWidth = 43,
        sepPadding = 5,
        backTopClass = '_j_btop',
        scrollTipHTML = '<a title="返回顶部" class="spr_icons return_top _j_btop" style="display:none" href="#" id="_j_btop"></a>';

    return {

        'container' : 'body',

        'main' : function() {
            this.getScrollTip();
            if(referDOM.length) {
                this.setPosition();
                this.bindEvents();
                this.checkDisplay();
            }
        },

        'bindEvents' : function() {
            K.on('notification', $.proxy(this.processNotification, this));
            ScrollObserver.addObserver($.proxy(this.checkDisplay, this));
            K.on('waterfall:resize', $.proxy(this.setPosition, this));
            $(window).resize($.proxy(this.setPosition, this));
        },

        'processNotification' : function(args) {},

        'newscome' : function() {
            this.scrollTip.addClass('hasMsg');
            this.fixIE6Position();
        },

        'newsclear' : function() {
            this.scrollTip.removeClass('hasMsg');
            this.fixIE6Position();
        },

        'checkDisplay' : function() {
            if(this.meetCondition()) {
                this.fixIE6Position();
                if($.browser.msie) {
                    this.scrollTip.show();
                } else {
                    this.scrollTip.fadeIn();
                }
            } else {
                if($.browser.msie) {
                    this.scrollTip.hide();
                } else {
                    this.scrollTip.fadeOut();
                }
            }
        },

        'meetCondition' : function() {
            return Geometry.scrollTop() > Geometry.viewportHeight();
        },

        'getScrollTip' : function() {
            var scrollTip = $('#'+scrollTipID);
            if ( !scrollTip.length ) {
                scrollTip = $(scrollTipHTML).appendTo('body');
                scrollTip.click($.proxy(function(ev) {
                	if($.browser.msie && parseInt($.browser.version, 10) < 9) {
                    	$(document).scrollTop(0);
                    } else {
                    	this.scrollTo(0);
                    }
                    ev.preventDefault();
                }, this));
            }

            if ( $.browser.msie && $.browser.version == '6.0' ) {
                scrollTip.css('position', 'absolute');
                this.fixIE6Position = function() {
                    var bottomHeight = scrollTip.hasClass('hasMsg') ? 79 : 55;
                    scrollTip.css({'top' : Geometry.scrollTop() + Geometry.viewportHeight() - bottomHeight});
                };
            }
            this.scrollTip = scrollTip;
        },

        'setPosition' : function() {
            var scrollTip = this.scrollTip;
            this.fixIE6Position();
            if ( referDOM.offset().left <= scrollTipWidth + sepPadding ) {
                scrollTip.css( { 'left':'auto', 'right':sepPadding } );
            } else {
                scrollTip.css('left', referDOM.outerWidth() + referDOM.offset().left + sepPadding);
            }
        },

        'scrollTo' : function(position, callback) {
            var currPosition = document.documentElement.scrollTop || document.body.scrollTop,
                totalTime = 100,
                sepTime = 10,
                timeStep = totalTime/sepTime,
                minSpeed = 10,
                totalLength = currPosition - position,
                step = 2*(Math.abs(totalLength) - timeStep*minSpeed)/(timeStep*(timeStep-1));

            step = step <= 0 ? 0 : step;

            scroll();
            function scroll() {
                setTimeout(function() {

                    if(timeStep < 1) { timeStep = 1 }

                    var incre = (Math.abs(currPosition - position) > 150 ? (timeStep - 1)*step : 0) + minSpeed;
                    timeStep --;
                    if(totalLength > 0) {
                        incre = -incre;
                    }
                    currPosition += incre;


                    if((incre > 0 && currPosition > position) || (incre < 0 && currPosition < position)) {
                        currPosition = position;
                    }

                    $(document).scrollTop(currPosition);
                    if(currPosition != position) {
                        scroll();
                    } else {
                        (typeof callback === 'function') && callback();
                    }
                }, sepTime);
            }
        },

        'fixIE6Position' : $.noop
    };

});
